using CodePlex.TfsLibrary.ObjectModel;
using CodePlex.TfsLibrary.RepositoryWebSvc;
using CodePlex.UnitTestUtility;
using Xunit;

namespace CodePlex.CodePlexClientLibrary
{
    public class CommitViewPresenterTest
    {
        [Fact]
        public void CallsEngineCommitWhenShowViewReturnsTrue()
        {
            TestableCommitViewPresenter presenter = TestableCommitViewPresenter.Create();
            presenter.View.ShowView__Result = true;

            presenter.Run(@"C:\Foo");

            Assert.True(presenter.TfsEngine.Commit_Called);
            Assert.Equal(@"C:\Foo", presenter.TfsEngine.Commit_LocalPath);
            Assert.Equal(presenter.View.Message, presenter.TfsEngine.Commit_Message);
        }

        [Fact]
        public void DoesNotCallEngineCommitWhenShowViewReturnsFalse()
        {
            TestableCommitViewPresenter presenter = TestableCommitViewPresenter.Create();
            presenter.View.ShowView__Result = false;

            presenter.Run(@"C:\Foo");

            Assert.False(presenter.TfsEngine.Commit_Called);
        }

        [Fact]
        public void EmptyCommitListShowsNothingToCommitMessage()
        {
            TestableCommitViewPresenter presenter = TestableCommitViewPresenter.Create();
            presenter.TfsEngine.Status__CallbackData.Clear();

            presenter.Run(@"C:\Foo");

            Assert.True(presenter.View.DisplayNoItemsMessage__Called);
            Assert.False(presenter.View.ShowView__Called);
            Assert.Equal(@"C:\Foo", presenter.TfsEngine.Status_LocalPath);
            Assert.False(presenter.TfsEngine.Status_IncludeServer);
            Assert.True(presenter.TfsEngine.Status_Recursive);
        }

        [Fact]
        public void NonEmptyCommitListCallsViewPropertiesThenShowView()
        {
            TestableCommitViewPresenter presenter = TestableCommitViewPresenter.Create();

            presenter.Run(@"C:\Foo");

            Assert.False(presenter.View.DisplayNoItemsMessage__Called);
            Assert.True(presenter.View.ShowView__Called);
            Assert.Equal(@"C:\Foo", presenter.TfsEngine.Status_LocalPath);
            Assert.True(presenter.TfsEngine.Status_Recursive);
            Assert.False(presenter.TfsEngine.Status_IncludeServer);
            Assert.Equal(@"C:\Foo", presenter.TfsEngine.GetFolderInfo_Directory);
            Assert.Equal(presenter.TfsEngine.GetFolderInfo_Result.TfsUrl, presenter.View.TfsServerUrl_Value);
            Assert.Equal(presenter.TfsEngine.GetFolderInfo_Result.ServerPath, presenter.View.TfsServerPath_Value);
            Assert.Equal(presenter.TfsEngine.Status__CallbackData.Count, presenter.View.DisplayItem__Items.Count);

            for (int idx = 0; idx < presenter.View.DisplayItem__Items.Count; idx++)
                Assert.Equal(presenter.TfsEngine.Status__CallbackData[idx].SourceItem, presenter.View.DisplayItem__Items[idx]);
        }

        [Fact]
        public void ShowCompleteCalledWhenFinished()
        {
            TestableCommitViewPresenter presenter = TestableCommitViewPresenter.Create();
            presenter.View.ShowView__Result = true;

            presenter.Run(@"C:\Foo");

            Assert.Equal(presenter.TfsEngine.Commit__Result, presenter.View.ShowComplete_ChangesetId);
        }

        [Fact]
        public void ShowItemStatusCalled()
        {
            TestableCommitViewPresenter presenter = TestableCommitViewPresenter.Create();
            presenter.View.ShowView__Result = true;

            presenter.Run(@"C:\Foo");

            Assert.Equal(presenter.SourceItem, presenter.View.ShowItemStatus_Item);
            Assert.Equal(SourceItemResult.S_Ok, presenter.View.ShowItemStatus__Result);
        }

        class TestableCommitViewPresenter : CommitViewPresenter
        {
            public readonly SourceItem SourceItem;
            public readonly StubTfsEngine TfsEngine;
            public readonly StubCommitView View;

            TestableCommitViewPresenter(StubCommitView view,
                                        StubTfsEngine engine)
                : base(view, engine)
            {
                View = view;
                TfsEngine = engine;
                SourceItem = SourceItem.FromLocalItem(1, ItemType.File, SourceItemStatus.Modified, SourceItemStatus.Unmodified, @"C:\Foo\bar.txt", null, 1, 0, null);

                TfsEngine.GetSourceItem__Result = SourceItem;

                TfsEngine.Status__CallbackData.Clear();
                TfsEngine.Status__CallbackData.Add(new SourceItemCallbackData(SourceItem, SourceItemResult.S_Ok));

                TfsEngine.Commit__CommitList.Clear();
                TfsEngine.Commit__CommitList.Add(SourceItem);
            }

            public static TestableCommitViewPresenter Create()
            {
                return new TestableCommitViewPresenter(new StubCommitView(), new StubTfsEngine());
            }
        }
    }
}